#!/usr/bin/python

import argparse
from reportlab.platypus import SimpleDocTemplate, Table,TableStyle
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.platypus import PageBreak
from argparse import RawTextHelpFormatter

import random
from enum import Enum
import math
import wx


class Operations(Enum):
    plus="+"
    subtract = "-"
    product="×"
    divide="÷"  

class Mode(Enum):
    ordinary=u'普通模式'
    advanced=u'高级模式'

class Create:
    opt = Operations.plus
    first = 0
    second = 0
    result = 0
    operations = [Operations.plus]
    max = 100

    def __init__(self, max,operations):
        self.max = max
        self.operations = operations
        pass

    def create_operation(self):
        length = len(self.operations)
        idx = random.randint(0,length-1)
        return self.operations[idx]

    def create_num(self,min,max):
        sss = random.randint(min,max)
        return sss

    def unkown_num(self):
        return random.randint(1,3)
    
    def create_tuple(self, mode):
        length = str(len(str(self.max)))
        # （）中预留的数据比原来的要大2个字符，方便书写
        length1 = str(len(str(self.max))+2)
        if mode == Mode.advanced.value:
            unkown = self.unkown_num()
            if unkown == 1:
                strrr = "({:^" + length1+"}){}{:^"+length+"}={:^"+length+"}"
                return strrr.format("  ",self.opt.value,self.second,self.result)
            elif unkown == 2:
                strrr = "{:^" + length+"}{}({:^"+length1+"})={:^"+length+"}"
                return strrr.format(self.first,self.opt.value,"  ",self.result)
            else:
                strrr = "{:^" + length+"}{}{:^"+length+"}={:^"+length+"}"
                return strrr.format(self.first,self.opt.value,self.second,"  ")
        else:
            strrr = "{:^" + length+"}{}{:^"+length+"}={:^"+length+"}"
            return strrr.format(self.first,self.opt.value,self.second,"  ")
        
    def create_divisor(self, dividend):
        nums = []
        for x in range(1,dividend+1):
            if (dividend % x == 0):
                nums.append(x) 

        length = len(nums)
        idx = random.randint(0,length-1)
        return nums[idx]
        

    def create_calculation_formula(self, mode):
        self.opt = self.create_operation()
        self.first = self.create_num(0,self.max)
        match self.opt:
            case Operations.plus:
                self.second = self.create_num(0,self.max-self.first)
                self.result = self.first+self.second
            case Operations.subtract:
                self.second = self.create_num(0,self.first)
                self.result = self.first-self.second
            case Operations.product:
                prod_max = int(math.sqrt(self.max))
                self.first = self.create_num(1,prod_max)
                self.second = self.create_num(1,prod_max)
                self.result = self.first*self.second
            case Operations.divide:
                divide_max = int(math.sqrt(self.max))
                self.second = self.create_num(1,divide_max)
                self.result = self.create_num(1,divide_max)
                self.first = self.second*self.result
                            
        return self.create_tuple(mode)

def create_calc(pages,max,opts, mode):
    opp = []
    for opt in opts:
        if opt=='-':
            opp.append(Operations.subtract)
        elif opt=="×":
            opp.append(Operations.product)
        elif opt=="÷":
            opp.append(Operations.divide)
        else:
            opp.append(Operations.plus)
    
    create_formula = Create(max,opp)
    doc = SimpleDocTemplate("calc.pdf")
    story = []
    for i in range(pages):
        data = []
        for x in range(20):
            row = []
            for y in range(3):
                str = create_formula.create_calculation_formula(mode)
                row.append(str)
            data.append(row)
        styles = getSampleStyleSheet()
        style = styles['Normal']
        current_tab_style = TableStyle([
        ('FONTSIZE', (0,0), (-1,0), 12),
        ('FONTSIZE', (0,1), (-1,-1), 12),
        ('ALIGN',(0,0),(-1,0),'LEFT'),
        ('ALIGN',(0,1),(-1,-1),'LEFT'),
        ])

        t=Table(data,rowHeights=[33]*20,colWidths=[2.3*inch]*4,style=current_tab_style)
        story.append(t)

    
    doc.build(story)
    
title = "小学数学加分神器"

class mainFrame(wx.Frame):
    pages=2
    max=100
    opt=[u'+',u'-',u'*']
    def __init__(self, parent):
        wx.Frame.__init__(self,parent,-1,title,style=wx.MINIMIZE_BOX|wx.CLOSE_BOX|wx.CAPTION)
        self.SetBackgroundColour(wx.Colour(250,250,250))
        self.SetSize((520,275))
        self.Center()

        tips = wx.StaticText(self, label = u'创建加/减/乘/除的算式的PDF文件，文件固定以calc.pdf命名，创建的文件会在这个工具的同一个目录下，此文档每页固定生成60题，可以包括加减乘除四种算式，加减法的最大数是100，乘除法的最大数是根号100，即10。模式选择中的“普通模式”只生成计算结果的算式，“高级模式”生成的算式需要计算的不一定是结果。',pos=(10,10),size=(450,80),style=wx.ALIGN_LEFT)
        tips.SetForegroundColour(wx.BLUE)

        wx.StaticText(self, -1,u'页数: ',pos=(10,120),size=(50,-1),style=wx.ALIGN_RIGHT)
        self.tc1 = wx.TextCtrl(self,-1,u'2',pos=(70,120),size=(70,-1),name=u'Pages',style=wx.TE_CENTER)
        self.tc1.Bind(wx.EVT_TEXT,self.EvtText)


        wx.StaticText(self, -1,u'最大数:',pos=(10,170),size=(50,-1),style=wx.ALIGN_RIGHT)
        self.tc2 = wx.TextCtrl(self,-1,u'100',pos=(70,170),size=(70,-1),name=u'Max',style=wx.TE_CENTER)
        self.tc2.Bind(wx.EVT_TEXT,self.EvtText)


        wx.StaticText(self, -1,u'算式：',pos=(170,120),size=(50,-1),style=wx.ALIGN_RIGHT)
        self.check_list_box = wx.CheckListBox(self,-1,choices=[u'+',u'-',u'×',u'÷'],pos=(220,120),size=(70,-1),name=u'Opt',style=wx.TE_CENTER)
        self.check_list_box.Bind(wx.EVT_CHECKLISTBOX,self.check_list,self.check_list_box)
        self.check_list_box.SetCheckedItems([0,1,2])


        wx.StaticText(self, -1,u'Copyright © 2024-2099 YiChen Luo Tashan Primary School, All Rights Reserved',pos=(10,210),size=(500,-1),style=wx.ALIGN_LEFT)

        self.btn_true = wx.Button(self, -1,u'生成',pos=(350,120),size=(100,25))
        self.btn_true.Bind(wx.EVT_LEFT_DOWN,self.OnLeftDown)

        self.radio_mode = wx.RadioBox(self, -1,u'模式选择',pos=(350,150),size=(150,-1),choices=[u'普通模式',u'高级模式'],style=wx.RA_SPECIFY_COLS)
        self.radio_mode.Bind(wx.EVT_RADIOBOX,self.OnRadioBox)

        self.Bind(wx.EVT_SIZE,self.OnSize)


    def EvtText(self,evt):
        '''输入框事件函数'''

        obj=evt.GetEventObject()
        objName = obj.GetName()
        text = evt.GetString()

        if objName == u'Pages':
            self.tc1.SetValue(text)
            self.pages = int(text)
        elif objName == u'Max':
            self.tc2.SetValue(text)
            self.max = int(text)
        pass

    def OnClose(self, evt):
        '''关闭窗口事件函数'''

        dlg = wx.MessageBox(u'确定要关闭吗？',u'操作提示',wx.YES_NO|wx.ICON_QUESTION)
        if dlg.ShowModal == wx.ID_YES:
            self.Destroy()
        pass

    def OnLeftDown(self, evt):
        '''左键按下事件'''
        try:
            create_calc(self.pages,self.max,self.opt, self.radio_mode.GetItemLabel(self.radio_mode.GetSelection()))
            wx.MessageBox(u'创建成功',u'操作提示',wx.OK|wx.ICON_INFORMATION) 
        except Exception as e:
            str = u"创建失败，如果pdf已打开，请关闭后再尝试，如果还是无法创建，请检查参数和运行环境或联系骆一辰爸爸！！！"
            print(e)
            wx.MessageBox(str,u'操作提示',wx.OK|wx.ICON_ERROR)

    def check_list(self, evt):
        obj = evt.GetEventObject()
        self.opt = obj.GetCheckedStrings()
        pass

    def OnSize(self,evt):
        pass  
    
    def OnRadioBox(self, evt):
        print(self.radio_mode.GetItemLabel(self.radio_mode.GetSelection()))
        pass


class mainApp(wx.App):
    def OnInit(self):
        self.SetAppName(title)
        self.Frame=mainFrame(None)
        self.Frame.Show()
        return True

if __name__ == '__main__':
    app = mainApp()
    app.MainLoop()
